package com.yoki.free.user.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.platform.result.Result;
import com.yoki.free.user.request.PostRequest;
import com.yoki.free.user.request.UserDTO;
import com.yoki.free.user.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;


/**
 * @ClassName UserController
 * @Description TODO
 * @Author yoki
 * @Date 2020-12-29 15:06
 * @Vsersion 1.0
 */
@RestController
@RequestMapping(value = "user")
@Api(tags = "用户管理")
public class UserController {

    @Autowired
    private IUserService userService;

    @Value("${spring.datasource.maxActive}")
    private String nacosMaxActiveType;

    @Value("${server.port}")
    private Integer serverPort;

    @Autowired
    private RedissonClient redisson;

    @Autowired
    private RedisTemplate<String, String> template;

    @ApiOperation(value = "缓存测试设置值")
    @GetMapping(value = "redis/set")
    public Result redisSet(@RequestParam("id") String id) {
        RMap<String, String> m = redisson.getMap("test", StringCodec.INSTANCE);
        m.put("1", id);
        return Result.success("设置成功");
    }

    @ApiOperation(value = "缓存测试获取值")
    @GetMapping(value = "redis/get")
    public Result redisGet() {
        BoundHashOperations<String, String, String> hash = template.boundHashOps("test");
        String t = hash.get("1");
        return Result.success(t);
    }

    @GetMapping(value = "list")
    @ApiOperation(value = "list接口")
    public Object list(){
        return "查询到了全部";
    }

    @PostMapping(value = "list/post")
    @ApiOperation(value = "list的post接口")
    public Result<PostRequest> listPost(@RequestBody @Valid PostRequest postRequest){
        return Result.data(postRequest);
    }

    @GetMapping(value = "exception")
    @ApiOperation(value = "自定义异常及返回测试接口")
    public Result<String> exception() {
        return Result.data(userService.exception());
    }

    @GetMapping(value = "nacos")
    @ApiOperation(value = "nacos接口")
    public Object nacos(){
        return Result.data(nacosMaxActiveType);
    }

    @GetMapping(value = "api/by/id")
    @ApiOperation(value = "Fegin Get测试接口")
    public Result queryUserById(@RequestParam("id") String id){
        return Result.data(id);
    }

    @PostMapping(value = "api/by/dto")
    @ApiOperation(value = "Fegin Post测试接口")
    public Result queryUserDto(@RequestBody @Valid UserDTO userDto){
        return Result.data(userDto);
    }

    @GetMapping(value = "api/ribbon")
    @ApiOperation(value = "Ribbon调用测试接口")
    public Result<String> testRibbon() {
        return Result.data("现在访问的服务端口是:" + serverPort);
    }

    @GetMapping(value = "sentinel/protected")
    @ApiOperation(value = "限流测试")
    @SentinelResource(value = "sentinelProtected")
    public Result<String> sentinelProtected() {
        return Result.data("访问的是限流测试接口");
    }

    @ApiOperation(value = "慢调用比例熔断策略")
    @GetMapping(value = "sentinel/slow/request/ratio")
    public Result<String> sentinelRR() {
        try{
            Double randomNumber;
            randomNumber = Math.random();
            if (randomNumber >= 0 && randomNumber <= 0.80){
                Thread.sleep(300L);
            }else if (randomNumber >= 0.80 && randomNumber <= 0.80 + 0.10){
                Thread.sleep(10L);
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        return Result.success("慢调用比例熔断策略");
    }

    @ApiOperation(value = "异常比例熔断策略")
    @GetMapping(value = "sentinel/error/ratio")
    public Result sentinelRatio() {
        int i = 1/0;
        return Result.success("异常比例熔断策略");
    }

    @ApiOperation(value = "异常数熔断策略")
    @GetMapping(value = "sentinel/error/count")
    public Result sentinelCount() {
        int i = 1/0;
        return Result.success("异常数熔断策略");
    }

    @ApiOperation(value = "Gateway路由转发测试")
    @GetMapping(value = "gateway/forward")
    public Result gatewayForward() {
        return Result.success("user-server测试数据");
    }
}
